/*
 * Copyright (C) 2017-2021
 * All rights reserved, Designed By
 * Copyright authorization contact 18814114118
 */
package com.shop.cereshop.app.service.express.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.shop.cereshop.app.service.express.KuaiDi100Service;
import com.shop.cereshop.commons.domain.express.*;
import com.shop.cereshop.commons.domain.kuaidi.kd100.order.req.PlaceAnOrderByCReq;
import com.shop.cereshop.commons.domain.kuaidi.kd100.order.resp.Kd100BaseResp;
import com.shop.cereshop.commons.domain.kuaidi.kd100.order.resp.PlaceAnOrderByCResp;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.utils.HttpUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 快递100
 *
 * @author wangsong
 * @version 1.0.0
 * @mail 1720696548@qq.com
 * @date 2020/9/16 0016 10:27
 */
@Service("kuaidi100service")
public class KuaiDi100ServiceImpl implements KuaiDi100Service {

    //授权码
    @Value("${kd100.key}")
    private String key;

    //公司编号
    @Value("${kd100.customer}")
    private String customer;
    //接口地址
    @Value("${kd100.host}")
    private String kd100Host;

    //获取物流轨迹url
    @Value("${kd100.queryUrl}")
    private String queryUrl;

    //下单接口url
    @Value("${kd100.order.corder}")
    private String orderCorderapi;

    //下单回调接口地址
    @Value("${kd100.order.callBackUrl}")
    private String orderCallBackUrl;

    @Override
    public List<ShippingTrace> findTraces(String code, String formid) throws CoBusinessException, Exception {
        QueryTrackReq<QueryTrackParam> queryTrackReq = new QueryTrackReq<>();
        QueryTrackParam queryTrackParam = new QueryTrackParam();
        queryTrackParam.setCom(code);
        queryTrackParam.setNum(formid);
        queryTrackReq.setParam(queryTrackParam);
        queryTrackReq.setCustomer(customer);
        queryTrackReq.setSign(DigestUtils.md5Hex(new Gson().toJson(queryTrackParam) + key + customer).toUpperCase());
        HttpResult httpResult = HttpUtils.doPost(kd100Host + queryUrl, queryTrackReq);
        if (httpResult.getStatus() == 200 && StringUtils.isNotBlank(httpResult.getBody())) {
            QueryTrackResp queryTrackResp = JSON.parseObject(httpResult.getBody(), QueryTrackResp.class);
            ShippingDTO shippingDTO = new ShippingDTO();
            shippingDTO.setShipperCode(code);
            shippingDTO.setLogisticCode(formid);
            if (queryTrackResp != null && queryTrackResp.getData() != null) {
                List<ShippingTrace> shippingTraceList = new ArrayList<>();
                for (QueryTrackData queryTrackData : queryTrackResp.getData()) {
                    ShippingTrace trace = new ShippingTrace();
                    trace.setAcceptTime(queryTrackData.getTime());
                    trace.setAcceptStation(queryTrackData.getContext());
                    shippingTraceList.add(trace);
                }
                shippingDTO.setTraces(shippingTraceList);
                return shippingDTO.getTraces();
            }
        }
        return new ShippingDTO().getTraces();
    }

    /**
     * 参数名             是否必填  类型     说明
     * kuaidicom          是       string   快递公司的编码，一律用小写字母，见《快递公司编码》
     * recManName         是       string   收件人姓名
     * recManMobile       是       string   收件人的手机号，手机号和电话号二者其一必填
     * recManPrintAddr    是       string   收件人所在完整地址，如广东深圳市深圳市南山区科技南十二路2号金蝶软件园
     * sendManName        是       string   寄件人姓名
     * sendManMobile      是       string   寄件人的手机号，手机号和电话号二者其一必填
     * sendManPrintAddr   是       string   寄件人所在的完整地址，如广东深圳市深圳市南山区科技南十二路2号金蝶软件园B10
     * callBackUrl        是       string   callBackUrl订单信息回调
     * cargo              是       string   物品名称,例：文件
     * payment            否       string   支付方式，SHIPPER: 寄方付（默认），CONSIGNEE: 到付（中通不支持）
     * weight             否       string   物品总重量KG，不需带单位，例：1.5
     * remark             否       string   备注
     * dayType            否       string   预约日期，例如：今天/明天/后天
     * pickupStartTime    否       string   预约起始时间，24小时制（HH:mm），例如：09:00
     * pickupEndTime      否       string   预约截止时间，24小时制（HH:mm），例如：10:00
     * salt               否       string   签名用随机字符串，salt为空时，传null用于加密
     * op                 否       string   是否开启订阅功能 0：不开启(默认) 1：开启 说明开启订阅功能时：pollCallBackUrl必须填入 此功能只针对有快递单号的单
     * pollCallBackUrl    否       string   如果op设置为1时，pollCallBackUrl必须填入，用于跟踪回调。此为免费服务，回调内容通过五、快递信息推送接口 返回（免费服务）
     * resultv2           否       string   添加此字段表示开通行政区域解析功能 。
     * 0：关闭（默认）
     * 1：开通行政区域解析功能以及物流轨迹增加物流状态名称
     * 4：开通行政解析功能以及物流轨迹增加物流高级状态名称、状态值并且返回出发、目的及当前城市信息(详见：快递信息推送接口文档)
     * thirdOrderId       否       string   平台订单号，最大32位。若此参数与之前的重复，48小时内返回第一次下单内容，否则会重新下单。
     */
    @Override
    public Kd100BaseResp placeAnOrderByC(PlaceAnOrderByCReq req) throws CoBusinessException {
        QueryTrackReq<PlaceAnOrderByCReq> queryTrackReq = new QueryTrackReq<>();
        queryTrackReq.setKey(key);
        queryTrackReq.setMethod("cOrder");
        queryTrackReq.setT(System.currentTimeMillis());
        req.setCallBackUrl(orderCallBackUrl);
        queryTrackReq.setParam(req);
        queryTrackReq.setCustomer(customer);
        queryTrackReq.setSign(DigestUtils.md5Hex(new Gson().toJson(req) + key + customer).toUpperCase());
        HttpResult httpResult = HttpUtils.doPost(kd100Host + orderCorderapi, queryTrackReq);
        if (httpResult.getStatus() == 200 && StringUtils.isNotBlank(httpResult.getBody())) {
            Kd100BaseResp<PlaceAnOrderByCResp> queryTrackResp = JSON.parseObject(httpResult.getBody(),
                    new com.alibaba.fastjson.TypeReference<Kd100BaseResp<PlaceAnOrderByCResp>>() {
                    });
            return queryTrackResp;
        }
        return Kd100BaseResp.builder()
                .result(false)
                .returnCode(String.valueOf(httpResult.getStatus()))
                .message(httpResult.getError())
                .build();
    }

    /**
     * 参数名        是否必填  类型     说明
     * taskId       是       string  任务ID
     * orderId      是       string  订单ID
     * cancelMsg    是       string  取消原因，例：暂时不寄件了，最大长度不超过30字符
     */
    @Override
    public Kd100BaseResp cancelOrderByC(PlaceAnOrderByCResp req) throws CoBusinessException {
        QueryTrackReq<PlaceAnOrderByCResp> queryTrackReq = new QueryTrackReq<>();
        queryTrackReq.setKey(key);
        queryTrackReq.setMethod("cOrder");
        queryTrackReq.setT(System.currentTimeMillis());
        queryTrackReq.setParam(req);
        queryTrackReq.setCustomer(customer);
        queryTrackReq.setSign(DigestUtils.md5Hex(new Gson().toJson(req) + key + customer).toUpperCase());
        HttpResult httpResult = HttpUtils.doPost(kd100Host + orderCorderapi, queryTrackReq);
        if (httpResult.getStatus() == 200 && StringUtils.isNotBlank(httpResult.getBody())) {
            Kd100BaseResp<PlaceAnOrderByCResp> queryTrackResp = JSON.parseObject(httpResult.getBody(),
                    new com.alibaba.fastjson.TypeReference<Kd100BaseResp<PlaceAnOrderByCResp>>() {
                    });
            return queryTrackResp;
        }
        return Kd100BaseResp.builder()
                .result(false)
                .returnCode(String.valueOf(httpResult.getStatus()))
                .message(httpResult.getError())
                .build();
    }

    /**
     * 参数名             是否必填  类型     说明
     * kuaidicom          是       string   快递公司编码，顺丰冷运、百世快运暂不支持价格查询。
     * serviceType        否       string   业务类型，顺丰速运需要传业务类型为"顺丰标快"，其他快递公司可不传
     * sendManPrintAddr   是       string   出发地地址，最小颗粒到市级，例如：广东省深圳市。（注意：京东快递需传详细收发地址查询价格；顺丰需到区级）
     * recManPrintAddr    是       string   目的地地址，最小颗粒到市级，例如：广东省深圳市。（注意：京东快递需传详细收发地址查询价格；顺丰需到区级）
     * weight             否       string   物品总重量KG，不需带单位，例：1.5
     */
    @Override
    public Kd100BaseResp queryPriceByC(PlaceAnOrderByCReq req) throws CoBusinessException {
        // 使用Fastjson将req转换为JSONObject，然后过滤掉空值字段
        JSONObject jsonObject = (JSONObject) JSON.toJSON(req);
        Map<String, Object> filteredParams = new HashMap<>();
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            if (entry.getValue() != null && !"".equals(entry.getValue())) {
                filteredParams.put(entry.getKey(), entry.getValue());
            }
        }

        QueryTrackReq<Map<String, Object>> queryTrackReq = new QueryTrackReq<>();
        queryTrackReq.setParam(filteredParams);
        queryTrackReq.setCustomer(customer);
        queryTrackReq.setKey(key);
        queryTrackReq.setMethod("cOrder");
        queryTrackReq.setT(System.currentTimeMillis());
        queryTrackReq.setSign(DigestUtils.md5Hex(new Gson().toJson(req) + key + customer).toUpperCase());
        HttpResult httpResult = HttpUtils.doPost(kd100Host + orderCorderapi, queryTrackReq);
        if (httpResult.getStatus() == 200 && StringUtils.isNotBlank(httpResult.getBody())) {
            Kd100BaseResp<Map<String, String>> queryTrackResp = JSON.parseObject(httpResult.getBody(),
                    new com.alibaba.fastjson.TypeReference<Kd100BaseResp<Map<String, String>>>() {
                    });
            return queryTrackResp;
        }
        return Kd100BaseResp.builder()
                .result(false)
                .returnCode(String.valueOf(httpResult.getStatus()))
                .message(httpResult.getError())
                .build();
    }
}
